home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr09 / vstsrc.zip / VSTDATE.C < prev    next >
C/C++ Source or Header  |  1995-01-26  |  16KB  |  493 lines

  1. /*
  2.  * %W% %E% %U%  [EXTREL_1.2]
  3.  *
  4.  * VersaTrack orbit calculations are based on those that appear in Dr. Manfred
  5.  * Bester's sattrack program (the Unix(tm) versions 1 and 2).
  6.  *
  7.  * The data from which the maps where generated come from "xsat", an
  8.  * X-Windows program by David A. Curry (N9MSW).
  9.  *
  10.  * Site coordinates come from various sources, including a couple of
  11.  * World Almanacs, and also from both of the programs mentioned above.
  12.  *
  13.  * The following are authors' applicable copyright notices:
  14.  *
  15.  *                                                                               
  16.  * Copyright (c) 1992, 1993, 1994 Manfred Bester. All Rights Reserved.        
  17.  *                                                                           
  18.  * Permission to use, copy, modify, and distribute this software and its      
  19.  * documentation for educational, research and non-profit purposes, without   
  20.  * fee, and without a written agreement is hereby granted, provided that the  
  21.  * above copyright notice and the following three paragraphs appear in all    
  22.  * copies.                                                                    
  23.  *                                                                              
  24.  * Permission to incorporate this software into commercial products may be    
  25.  * obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,     
  26.  * Berkeley, CA 94709, USA.                                                   
  27.  *                                                                             
  28.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,  
  29.  * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF    
  30.  * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED   
  31.  * OF THE POSSIBILITY OF SUCH DAMAGE.                                         
  32.  *                                                                             
  33.  * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT       
  34.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A    
  35.  * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"       
  36.  * BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,  
  37.  * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.                                   
  38.  *                                                                             
  39.  *                                                                             
  40.  * Copyright 1992 by David A. Curry                                            
  41.  *                                                                             
  42.  * Permission to use, copy, modify, distribute, and sell this software and its 
  43.  * documentation for any purpose is hereby granted without fee, provided that  
  44.  * the above copyright notice appear in all copies and that both that copyright
  45.  * notice and this permission notice appear in supporting documentation.  The  
  46.  * author makes no representations about the suitability of this software for  
  47.  * any purpose.  It is provided "as is" without express or implied warranty.   
  48.  *                                                                             
  49.  * David A. Curry, N9MSW                                                       
  50.  * Purdue University                                                           
  51.  * Engineering Computer Network                                                
  52.  * 1285 Electrical Engineering Building                                        
  53.  * West Lafayette, IN 47907                                                    
  54.  * davy@ecn.purdue.edu                                                         
  55.  *                                                                             
  56.  * VersaTrack Copyright (c) 1993, 1994 Siamack Navabpour. All Rights Reserved.
  57.  *
  58.  * Permission is hereby granted to copy, modify and distribute VersaTrack
  59.  * in whole, or in part, for educational, non-profit and non-commercial use
  60.  * only, free of charge or obligation, and without agreement, provided that
  61.  * all copyrights and restrictions noted herein are observed and followed, and
  62.  * additionally, that this and all other copyright notices listed herein
  63.  * appear unaltered in all copies and in all derived work.
  64.  *
  65.  * This notice shall not in any way void or supersede any of the other authors
  66.  * rights or privileges.
  67.  *
  68.  * VersaTrack IS PRESENTED FREE AND "AS IS", WITHOUT ANY WARRANTY OR SUPPORT.
  69.  * YOU USE IT AT YOUR OWN RISK. The author(s) shall not be liable for any
  70.  * direct, indirect, incidental, or consequential damage, loss of profits or
  71.  * other tangible or intangible losses or benefits, arising out of or related
  72.  * to its use. VersaTrack carries no warranty, explicit or implied, including
  73.  * but not limited to those of merchantablity and fitness for a particular
  74.  * purpose.
  75.  *
  76.  * Siamack Navabpour, 12342 Hunter's Chase Dr. Apt. 2114, Austin, TX 78729.
  77.  * sia@bga.com or sia@realtime.com.
  78.  */
  79.  
  80.  
  81. #include <windows.h>
  82. #include <stdio.h>
  83. #include <math.h>
  84. #include <time.h>
  85. #include <string.h>
  86. #include <stdlib.h>
  87.  
  88. #include "vstdefs.h"
  89. #include "constant.h"
  90. #include "vsttype.h"
  91. #include "vstextrn.h"
  92.  
  93. static int  month_days[] = {
  94.     0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
  95. };
  96.  
  97. static char *daynames[]  = {
  98.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  99. };
  100.  
  101. long day_number(year,month,day)
  102. int year, month, day;
  103. {
  104.     long result;
  105.     
  106.     if (year < 50)                 /* allows 4 or 2 digit year specifications */
  107.         year += 2000;
  108.     else
  109.         if (year < 100)
  110.             year += 1900;
  111.  
  112.     result = ((((long) year - 1901) * 1461) >> 2) 
  113.              + month_days[month-1] + day + 365;
  114.  
  115.     if (year%4 == 0 && month > 2)         /* correct day number for leap year */
  116.         result++;
  117.  
  118.     return result;
  119. }
  120.  
  121. /*
  122.  * siderealtime: calculates sidereal time. For reference see:
  123.  *  "The Astronomical Almanac", 1983, page B6
  124.  *
  125.  *  gmsTime    = Greenwich mean sidereal time
  126.  *  gasTime    = Greenwich apparent sidereal time
  127.  *  lasTime    = local apparent sidereal time
  128.  *  equEquinox = equation of the equinoxes
  129.  */
  130.  
  131. void siderealtime(tp, timeArg)
  132. track_t *tp;
  133. double timeArg;
  134. {
  135.     double Tu, Ru, utcInterv, gmsTime;
  136.     extern double eqxnutation(track_t *);
  137.  
  138.     tp->juliandate = timeArg + JULDAT1900 - 0.5;                     /* [d] */
  139.     
  140.     utcInterv  = reduce(tp->juliandate-floor(tp->juliandate)-0.5, ZERO, ONE);  /* [d] */
  141.     Tu         = (tp->juliandate - utcInterv - JULDAT1900) / JULCENT; /* [jcy] */
  142.     Ru         = 2.580556e-5 * Tu*Tu + 2400.051262 * Tu + 6.646065556; /* [h] */
  143.  
  144.     gmsTime    = (Ru / 24.0 + utcInterv * SIDSOLAR) * TWOPI;         /* [rad] */
  145.     gmsTime    = reduce(gmsTime, ZERO, TWOPI);                       /* [rad] */
  146.  
  147.     if (fabs(tp->juliandate - tp->lastjdate) >= NUTEUPDATEINT) {
  148.         tp->equinox = eqxnutation(tp);
  149.         tp->lastjdate = tp->juliandate;
  150.     }
  151.     
  152.     tp->gastime= reduce (gmsTime + tp->equinox, ZERO, TWOPI);        /* [rad] */
  153.     tp->lastime = reduce (tp->gastime - tp->sitep->c_lng, ZERO, TWOPI); /* [rad] */
  154. }
  155.  
  156.  
  157. static void
  158. daytoymdyd(daynum, year, month, day, yearday)
  159. long daynum;
  160. int  *year, *month, *day, *yearday;
  161.  
  162. {
  163.     long Y;
  164.     int  M, L;
  165.  
  166.     Y         = 4 * daynum;
  167.     Y        /= 1461;
  168.     daynum   -= 365 + (((Y - 1) * 1461) >> 2);
  169.     *yearday  = daynum;
  170.  
  171.     L = 0;
  172.     if (Y%4 == 0 && daynum > month_days[2])
  173.         L = 1;
  174.  
  175.     M = 1;
  176.     while (daynum > month_days[M] + L)
  177.         M++;
  178.  
  179.     daynum -= (month_days[M-1]);
  180.     if (M > 2)
  181.         daynum -= L;
  182.    
  183.     *year  = Y + 1900;
  184.     *month = M;
  185.     *day   = daynum;
  186. }
  187.  
  188.  
  189. void printDate(fp,time, sitep, flags)
  190. double time;
  191. FILE   *fp;
  192. site_t *sitep;
  193. int flags;
  194. {
  195.     long daynum;
  196.     int  day, month, year, yearDay;
  197.  
  198.     if (flags & SE_GTR_LOC) {
  199.         time += timeZone;
  200.     }
  201.     else if (flags & SE_GTR_SLT) {
  202.         time += sitep ? sitep->c_timezone : 0.0;
  203.     }
  204.  
  205.     daynum = (long) time;
  206.     daytoymdyd(daynum, &year, &month, &day, &yearDay);
  207.  
  208.     fprintf(fp,"%s %02d/%02d/%02d", daynames[daynum%7], month,
  209.         day, year-1900);
  210. }
  211.  
  212.  
  213. void printTime(fp, time, sitep, flags)
  214. FILE *fp;
  215. double time;
  216. site_t *sitep;
  217. unsigned int flags;
  218. {
  219.     char  buf[16];
  220.  
  221.     timeStr(time, sitep, flags, 1, buf);
  222.     buf[8] = 0;
  223.     fprintf(fp,"%s", buf);
  224. }
  225.  
  226. void timeStr(time, sitep, flags, gtr, str)
  227. double time;
  228. site_t *sitep;
  229. unsigned int flags;
  230. int gtr;
  231. char *str;
  232. {
  233.     double dayTime;
  234.     long   dayNum;
  235.     int    hours, mins, secs, dummyi;
  236.     char *tzstr;
  237.  
  238.     tzstr = "UTC";
  239.     if (gtr) {
  240.         if (flags & SE_GTR_LOC) {
  241.             time += timeZone;
  242.             tzstr = timeZoneName;
  243.         }
  244.         else if (flags & SE_GTR_SLT) {
  245.             time += sitep ? sitep->c_timezone : 0.0;
  246.             tzstr = sitep ? sitep->c_tzname : "UTC" ;
  247.         }
  248.     }
  249.     else {
  250.         if (flags & SE_RTD_LOC) {
  251.             time += timeZone;
  252.             tzstr = timeZoneName;
  253.         }
  254.         else if (flags & SE_RTD_SLT) {
  255.             time += sitep ? sitep->c_timezone : 0.0;
  256.             tzstr = sitep ? sitep->c_tzname : "UTC" ;
  257.         }
  258.     }
  259.     dayNum  = (long) time;
  260.     dayTime = time - (double) dayNum;
  261.     timetodhms(dayTime, &dummyi, &hours, &mins, &secs);
  262.     sprintf(str,"%02d:%02d:%02d  %s", hours, mins, secs, tzstr);
  263. }
  264.  
  265. void durStr(time, str)
  266. double time;
  267. char *str;
  268. {
  269.     long   days;
  270.     int    hours, mins, secs, dummyi;
  271.  
  272.     days  = (long) time;
  273.     timetodhms(time - (double) days, &dummyi, &hours, &mins, &secs);
  274.     sprintf(str,"%02d:%02d:%02d:%02d", days, hours, mins, secs);
  275. }
  276.  
  277. static void
  278. timetodhms(time, days, hours, mins, secs)
  279. double time;
  280. int    *days, *hours, *mins, *secs;
  281.  
  282. {
  283.     double timed, timeh, timem, times;
  284.  
  285.     timed  = time;
  286.     timeh  = 24.0 *   modf(timed,&timed);
  287.     timem  = 60.0 *   modf(timeh,&timeh);
  288.     times  = 60.0 *   modf(timem,&timem);
  289.     times +=          modf(times,×);
  290.  
  291.     if (fabs(times - 60.0) < 5.0e-4) {
  292.         times  = 0.0;
  293.         timem += 1.0;
  294.         if (fabs(timem - 60.0) < 1.0e-4) {
  295.             timem  = 0.0;
  296.             timeh += 1.0;
  297.             if (fabs(timeh - 24.0) < 1.0e-4) {
  298.                 timeh  = 0.0;
  299.                 timed += 1.0;
  300.             }
  301.         }
  302.     }
  303.     *days  = (int) timed;
  304.     *hours = (int) timeh;
  305.     *mins  = (int) timem;
  306.     *secs  = (int) times;
  307. }
  308.  
  309.  
  310. void
  311. dateStr(time, sitep, flags, gtr, string)
  312. double time;  /* in day units + fractions */
  313. site_t *sitep;
  314. unsigned int flags; /* time zone difference in day units + day fractions */
  315. int gtr;
  316. char *string;
  317. {
  318.     double dayTime;
  319.     long dayNum;
  320.     int  day, month, year, yearDay, hours, mins, secs, idummy;
  321.     char *tzstr;
  322.  
  323.     tzstr = "UTC";
  324.     if (gtr) {
  325.         if (flags & SE_GTR_LOC) {
  326.             time += timeZone;
  327.             tzstr = timeZoneName;
  328.         }
  329.         else if (flags & SE_GTR_SLT) {
  330.             time += sitep ? sitep->c_timezone : 0.0;
  331.             tzstr = sitep ? sitep->c_tzname : "UTC";
  332.         }
  333.     }
  334.     else {
  335.         if (flags & SE_RTD_LOC) {
  336.             time += timeZone;
  337.             tzstr = timeZoneName;
  338.         }
  339.         else if (flags & SE_RTD_SLT) {
  340.             time += sitep ? sitep->c_timezone : 0.0;
  341.             tzstr = sitep ? sitep->c_tzname : "UTC";
  342.         }
  343.     }
  344.     dayNum = (long) time;
  345.     daytoymdyd(dayNum, &year, &month, &day, &yearDay);
  346.     dayTime = time - (double) dayNum;
  347.     timetodhms(dayTime, &idummy, &hours, &mins, &secs);
  348.  
  349.     sprintf(string, "%02d/%02d/%02d %02d:%02d:%02d %-3.3s", month, day, year-1900,
  350.         hours, mins, secs, tzstr);
  351. }
  352.  
  353. double
  354. utctime()
  355. {
  356.     double daynum;
  357.     double hour;
  358.     SYSTEMTIME tm;
  359.  
  360.     GetSystemTime(&tm);
  361.  
  362.     daynum    = day_number(tm.wYear, tm.wMonth, tm.wDay);
  363.     hour      = (double) tm.wHour + (double)tm.wMinute / 60.0 +
  364.                 (double) tm.wSecond/3600.0 + (double)tm.wMilliseconds / (3600.0 * 1000.0);
  365.     return  daynum + hour / 24.0 + ( 5/SPD ) ;
  366. }
  367.  
  368. void calendar(year,yearday,pmonth,pday)
  369. int year, yearday, *pmonth, *pday;
  370. {
  371.     int month, day, offset;
  372.  
  373.     static char monthdays[26] = {
  374.         0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* non-leap */
  375.         0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31  /* leap */
  376.     };
  377.  
  378.     /*
  379.      * is "year" is a leap year ?
  380.      * leap years    : 1600, 1984, 1988, 1992, 1996, 2000 etc.  
  381.      * non-leap years : 1700, 1800, 1900, 2100 etc.
  382.      */
  383.      
  384.     offset = ((year%4 == 0) && (year%100 == 0) && (year%400 != 0)) ? 13 : 0;
  385.  
  386.     month = 0;
  387.     while (yearday > 0) {
  388.         month++;
  389.         yearday -= (int) monthdays[month+offset];
  390.     }
  391.     
  392.     day = yearday + (int) monthdays[month+offset];
  393.     
  394.     *pmonth = month;
  395.     *pday   = day;
  396. }
  397.  
  398.  
  399. char *monthname(month)
  400. int  month;
  401. {
  402.     static char *name[] = { "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  403.                             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  404.  
  405.     return (month < 1 || month > 12) ? name[0] : name[month];
  406. }
  407.  
  408.  
  409. double internalTime( yr, mon, day, hour, min, sec)
  410. int yr, mon, day, hour, min, sec;
  411. {
  412.     double t, h;
  413.     
  414.     t  = (double) day_number(yr, mon, day);
  415.     h  = (double) hour + (double) min / 60.0 + (double)sec / 3600.0;
  416.     t += h / 24.0;
  417.     
  418.     return t;
  419. }
  420.  
  421. double
  422. dateStrtoTime(char * buf)
  423. {
  424.     int mm,dd,yy,hh,min,ss;
  425.     char ch, *tzp;
  426.     double t;
  427.  
  428.     stripTrailingSpace(buf);
  429.     if (sscanf(buf,"%02d-%02d-%02d %02d:%02d:%02d", &mm,&dd,&yy,&hh,&min,&ss) != 6)
  430.         if (sscanf(buf,"%02d/%02d/%02d %2d:%02d:%02d", &mm,&dd,&yy,&hh,&min,&ss) != 6)
  431.             return -1.0;            
  432.  
  433.     tzp = timeZoneName;
  434.     t = internalTime(yy, mm, dd, hh, min, ss);
  435.  
  436.     if (strlen(buf) > 3) {
  437.         ch = buf[strlen(buf)-3];
  438.         if (ch != ':' ) {
  439.             tzp = buf + strlen(buf) - 3;
  440.             if (!cistrcmp(tzp, "LOC") || !cistrcmp(tzp, timeZoneName))
  441.                 t -= timeZone;
  442.             else if (cistrcmp(tzp,"UTC") && cistrcmp(tzp,"GMT")) {
  443.                 sprintf(tmpbuf, "Timezone name must be one of %s, LOC, UTC, or GMT",
  444.                         timeZoneName);
  445.                 usermsg(tmpbuf);
  446.                 return -1.0;
  447.             }
  448.         }
  449.     }
  450.     return t;
  451. }
  452.  
  453. void
  454. dateOnlyStr(time, sitep, flags, gtr, string)
  455. double time;  /* in day units + fractions */
  456. site_t *sitep;
  457. unsigned int flags; /* time zone difference in day units + day fractions */
  458. int gtr;
  459. char *string;
  460. {
  461.     long dayNum;
  462.     int  day, month, year, yearDay;
  463.     char *tzstr;
  464.  
  465.     tzstr = "UTC";
  466.     if (gtr) {
  467.         if (flags & SE_GTR_LOC) {
  468.             time += timeZone;
  469.             tzstr = timeZoneName;
  470.         }
  471.         else if (flags & SE_GTR_SLT) {
  472.             time += sitep ? sitep->c_timezone : 0.0;
  473.             tzstr = sitep ? sitep->c_tzname : "UTC";
  474.         }
  475.     }
  476.     else {
  477.         if (flags & SE_RTD_LOC) {
  478.             time += timeZone;
  479.             tzstr = timeZoneName;
  480.         }
  481.         else if (flags & SE_RTD_SLT) {
  482.             time += sitep ? sitep->c_timezone : 0.0;
  483.             tzstr = sitep ? sitep->c_tzname : "UTC";
  484.         }
  485.     }
  486.     dayNum = (long) time;    
  487.     daytoymdyd(dayNum, &year, &month, &day, &yearDay);
  488.         
  489.     sprintf(string,"%s %s %02d %d", daynames[dayNum%7], monthname(month), day, year);
  490. }
  491.  
  492.  
  493.